<script setup>
import { ref, nextTick, computed } from 'vue';
import { onLoad, onShow } from '@dcloudio/uni-app';
import { request, socket } from '@/request/request';
import TnIcon from '@tuniao/tnui-vue3-uniapp/components/icon/src/icon.vue'
import TnNavbar from '@tuniao/tnui-vue3-uniapp/components/navbar/src/navbar.vue'
import { useI18n } from 'vue-i18n';
import LoginAuth from '../components/LoginAuth.vue'
import { DOMAIN_NAME } from '@/request/config'

const { t } = useI18n();

// 消息
const messages = ref([]);

const userInfo = ref(uni.getStorageSync('aichat_user') || {});
const uyghurRegex = /[\u0600-\u06FF\u0750-\u077F\u08A0-\u08FF]/;
const ug = ref(false);
const newMessage = ref('');
const myAvatar = computed(() => userInfo.value.avatar ? DOMAIN_NAME + '/file/' + userInfo.value.avatar : '/static/avatar-ceeb03f6.jpg');
const otherAvatar = '/static/bot-bro.png'; // 替换为对方的头像路径
const isTyping = ref(false); // 模拟对方正在输入
const messageId = ref(2);
const lastMessageId = ref('message-1'); // 初始化为第一条消息的ID
const isStreamIndex = ref(0)
const canUseWebSocket = ref(false)


onLoad(() => {
  userInfo.value = uni.getStorageSync('aichat_user');
  console.log('userInfo', userInfo.value);
  const uuid = userInfo.value.id;
  socket.init({
    'user_id': uuid
  }, handleWebSocketMessage);
})
onShow(() => {
  if (messages.value.length === 0) {
    messages.value.push({
      text: t('index.welcome'),
      isMine: false,
      timestamp: new Date().getTime() - 300000,
      id: 1
    });
  };
});

// 处理输入事件
const handleInput = (event) => {
  const value = event.detail.value;
  ug.value = uyghurRegex.test(value);
};

// 发送消息
const sendMessage = () => {
  // 检查用户认证状态
  const userInfo = uni.getStorageSync('aichat_user');
  if (!userInfo?.auth) {
    uni.showToast({
      title: '请先完成认证',
      icon: 'none'
    });
    return;
  }

  const token = uni.getStorageSync('aichat_token');

  if (newMessage.value.trim()) {
    const newMsg = {
      text: newMessage.value,
      isMine: true,
      timestamp: new Date().getTime(),
      id: messageId.value++
    };
    messages.value.push(newMsg);
    lastMessageId.value = 'message-' + newMsg.id; // 更新最后一条消息的ID

    // 先创建会话获取chatID
    request.get('ai/create_chat', {}, {
      'Authorization': `Bearer ${token}`
    }, true, true).then(res => {
      console.log('先创建会话获取chatID', res);

      if (res.code === 200) {
        const chatID = res.data;
        // 发送消息到ai/chat接口
        request.post('ai/chat', {
          content: newMessage.value
        }, {
          'Authorization': `Bearer ${token}`,
        }, true, false, chatID).then(res => {
          if (res.code === 200) {
            newMessage.value = '';
            // 模拟对方正在输入
            isTyping.value = true;
            isStreamIndex.value = 0;
            canUseWebSocket.value = true; // 启用WebSocket通信
          } else {
            // 移除未成功发送的消息
            messages.value.pop();
            uni.showToast({
              title: '发送失败',
              icon: 'none'
            });
          }
        }).catch(err => {
          // 发送失败时移除消息
          messages.value.pop();
          console.error('发送消息失败:', err);
          uni.showToast({
            title: '发送失败',
            icon: 'none'
          });
        });
      }
    }).catch(err => {
      console.error('创建会话失败:', err);
      uni.showToast({
        title: '发送失败',
        icon: 'none'
      });
    });
  }
};

// 处理时间
const shouldShowTimestamp = (index) => {
  if (index === 0) return true;
  const currentMessage = messages.value[index];
  const previousMessage = messages.value[index - 1];
  return (currentMessage.timestamp - previousMessage.timestamp) > 120000; // 超过两分钟
};

const formatTimestamp = (timestamp) => {
  const date = new Date(timestamp);
  return `${date.getHours()}:${date.getMinutes().toString().padStart(2, '0')}`;
};

// WebSocket回调
const handleWebSocketMessage = (result) => {
  if (!canUseWebSocket.value) return; // 如果WebSocket未启用，直接返回
  isTyping.value = false;
  const {
    content,
    stream = false
  } = result.data;


  if (!stream) {
    // 创建一个新的消息对象
    const newMsg = {
      text: "",
      isMine: false,
      timestamp: new Date().getTime(),
      id: messageId.value++
    };
    messages.value.push(newMsg);
    lastMessageId.value = 'message-' + newMsg.id; // 更新最后一条消息的ID
    const messages_index = messages.value.findIndex((item) => item.id === newMsg.id);
    let charIndex = 0;
    const interval = setInterval(() => {
      if (charIndex < content.length) {
        messages.value[messages_index].text += content[charIndex];
        charIndex++;
        scrollToBottom();
      } else {
        clearInterval(interval);
      }
    }, 50); // 每100毫秒显示一个字符
  } else {
    if (isStreamIndex.value == 0) {
      const newMsg = {
        text: content,
        isMine: false,
        timestamp: new Date().getTime(),
        id: messageId.value++
      };
      messages.value.push(newMsg);
      isStreamIndex.value = messages.value.findIndex((item) => item.id === newMsg.id);
    }
    const interval = setInterval(() => {
      messages.value[isStreamIndex.value].text += content;
      scrollToBottom();
      clearInterval(interval);
    }, 100); // 每100毫秒显示一个字符
  }
};
// 滚动到底部
const scrollToBottom = () => {
  nextTick(() => {
    uni.createSelectorQuery()
      .select('#' + 'message-' + (messageId.value - 1))
      .boundingClientRect((rect) => {
        if (rect) {
          uni.pageScrollTo({
            scrollTop: rect.bottom,
            duration: 300
          });
        }
      })
      .exec();
  });
};
const showLoginAuth = ref(false)

const checkAuthAndSend = () => {
  const userInfo = uni.getStorageSync('aichat_user')
  if (!userInfo || !userInfo.auth) {
    showLoginAuth.value = true
    return
  }
  sendMessage()
}

const onLoginSuccess = () => {
  showLoginAuth.value = false
  sendMessage()
}

const setupClick = () => {
  uni.navigateTo({
    url: '/pages/setup/setup',
  })
}
</script>

<template>
  <!-- 顶部导航 -->
  <tn-navbar backgroundColor="#fff" fixed>{{ t('index.title') }}
    <template #back>
      <tn-icon name="set" size="40" @click="setupClick"></tn-icon>
    </template>
  </tn-navbar>
  <view class="chat-container">
    <scroll-view class="message-list" scroll-y :scroll-into-view="lastMessageId" show-scrollbar>
      <view v-for="(message, index) in messages" :key="message.id" :id="'message-' + message.id">
        <view v-if="shouldShowTimestamp(index)" class="timestamp">
          {{ formatTimestamp(message.timestamp) }}
        </view>
        <view :class="['message-item', message.isMine ? 'mine' : '']">
          <image :src="message.isMine ? myAvatar : otherAvatar" class="avatar" />
          <view class="message-bubble">
            <text>{{ message.text }}</text>
            <view :class="['bubble-tail', message.isMine ? 'mine-tail' : '']"></view>
          </view>
        </view>
      </view>
      <view v-if="isTyping" class="typing-indicator">
        <image :src="otherAvatar" class="avatar" />
        <view class="typing-bubble">
          <text class="dot">.</text>
          <text class="dot">.</text>
          <text class="dot">.</text>
        </view>
      </view>
    </scroll-view>
  </view>
  <view class="bottom-input-btn-container">
    <view class="input-container" :class="{ ug: ug }">
      <input v-model="newMessage" @input="handleInput" :style="{ marginRight: !ug ? '10px' : '' }"
        placeholder="输入消息..." />
      <button @click="checkAuthAndSend" :style="{ marginRight: ug ? '10px' : '' }">发送</button>
    </view>
  </view>
  <LoginAuth v-model:show="showLoginAuth" @login-success="onLoginSuccess" />
</template>

<style scoped>
.ug {
  direction: rtl;
}

.chat-container {
  display: flex;
  flex-direction: column;
  height: 100vh;
}

.text-container {
  background-color: red;
  height: calc(100vh-120rpx);
}

.message-list {
  padding-bottom: 160rpx;
}

.timestamp {
  text-align: center;
  color: #999;
  margin: 20rpx 0;
  font-size: 24rpx;
}

.message-item {
  display: flex;
  align-items: flex-start;
  margin-bottom: 20rpx;
}

.message-item.mine {
  flex-direction: row-reverse;
}

.avatar {
  width: 80rpx;
  height: 80rpx;
  border-radius: 40rpx;
  margin: 0 20rpx;
}

.message-bubble {
  position: relative;
  max-width: 70%;
  padding: 20rpx;
  background-color: #f6f6f6;
  border-radius: 10rpx;
}

.message-item.mine .message-bubble {
  background-color: #dcf8c6;
}

.bubble-tail {
  position: absolute;
  width: 0;
  height: 0;
  border-style: solid;
  top: 20rpx;
}

.bubble-tail.mine-tail {
  right: -10px;
  border-width: 20rpx 0 20rpx 20rpx;
  border-color: transparent transparent transparent #dcf8c6;
}

.bubble-tail:not(.mine-tail) {
  left: -10px;
  border-width: 20rpx 20rpx 20rpx 0;
  border-color: transparent #f6f6f6 transparent transparent;
}

.typing-indicator {
  display: flex;
  align-items: center;
  margin-bottom: 20rpx;
}

.typing-bubble {
  display: flex;
  max-width: 70%;
  padding: 20rpx;
  background-color: #f6f6f6;
  border-radius: 10rpx;
  font-style: italic;
  color: #999;
}

.dot {
  animation: blink 1.5s infinite;
  margin: 0 4prx;
}

.dot:nth-child(2) {
  animation-delay: 0.3s;
}

.dot:nth-child(3) {
  animation-delay: 0.6s;
}

@keyframes blink {

  0%,
  20%,
  50%,
  80%,
  100% {
    opacity: 0;
  }

  40% {
    opacity: 1;
  }

  60% {
    opacity: 1;
  }
}

.bottom-input-btn-container {
  background-color: #fff;
  position: fixed;
  bottom: 0;
  width: 100%;
  background: blue;
}

.input-container {
  display: flex;
  padding: 20rpx 20rpx 40rpx;
  background-color: #fff;
}

input {
  flex: 1;
  padding: 20rpx;
  height: 90rpx;
  border: 2rpx solid #ccc;
  border-radius: 10rpx;
}

button {
  padding: 0 40rpx;
  background-color: #007aff;
  color: #fff;
  border: none;
  border-radius: 10rpx;
}
</style>